# -*- coding: utf-8 -*-
from flask import current_app

import os
import re
import os.path as osp
import shutil
import git as PyGit
from git import Repo as PyRepo
from functools import cmp_to_key


def compare_version(version1=None, version2=None, split_flag="."):
    # 如果存在有为空的情况则进入
    if (version1 is None) or (version1 == "") or (version2 is None) or (version2 == ""):
        # version1为空且version2不为空，则返回version2大
        if ((version1 is None) or (version1 == "")) and (version2 is not None) and (version2 != ""):
            return 1
        # version2为空且version1不为空，则返回version1大
        if ((version2 is None) or (version2 == "")) and (version1 is not None) and (version1 != ""):
            return -1

    # 如果版本字符串相等，那么直接返回相等，这句会且只会在第一次比较时才可能进入
    # version1和version2都为空时也会进入这里
    if version1 == version2:
        return 0

    # 对版本字符串从左向右查找"."，第一个"."之前的字符串即为此次要比较的版本
    # 如1.3.5中的1
    try:
        current_section_version1 = version1[:version1.index(split_flag)]
    except Exception:
        current_section_version1 = version1
    try:
        current_section_version2 = version2[:version2.index(split_flag)]
    except Exception:
        current_section_version2 = version2
    # 对本次要比较的版本字符转成整型进行比较
    if int(current_section_version1) > int(current_section_version2):
        return -1
    elif int(current_section_version1) < int(current_section_version2):
        return 1

    # 如果本次传来版本字符串中已没有版本号分隔符，那说明本次比较的版本号已是最后一位版本号，下次比较值赋空
    # 如本次传来的是5，那下次要比较的只能赋空
    try:
        other_section_version1 = version1[version1.index(split_flag)+1:]
    except Exception:
        other_section_version1 = ""
    try:
        other_section_version2 = version2[version2.index(split_flag) + 1:]
    except Exception:
        other_section_version2 = ""

    # 递归调用比较
    return compare_version(other_section_version1, other_section_version2)


class Git:

    def __init__(self, url):
        self.url = url
        self.path = None

    def is_git_dir(self):
        """
        判断是否为git目录

        @param path:
        @return:
        """
        d = os.path.join(self.path, '.git')

        if osp.isdir(d):
            if osp.isdir(osp.join(d, 'objects')) and osp.isdir(osp.join(d, 'refs')):
                headref = osp.join(d, 'HEAD')
                return osp.isfile(headref) or \
                       (osp.islink(headref) and
                        os.readlink(headref).startswith('refs'))
            elif (osp.isfile(osp.join(d, 'gitdir')) and
                      osp.isfile(osp.join(d, 'commondir')) and
                      osp.isfile(osp.join(d, 'gitfile'))):
                return False
        return False

    def init(self, path, is_need_clone=False):
        self.path = path
        if os.path.exists(self.path):
            shutil.rmtree(self.path, ignore_errors=True)
        os.mkdir(path)
        if is_need_clone:
            return self.clone()

    def clone(self):
        """
        检出项目
        # -- 问题：gunicorn在daemon=True模式下执行svn命令正常，但是执行git命令失败.
        # -- 解决：gunicorn在daemon=True模式启动增加--enable-stdio-inheritance参数
        # cmd = ['svn', '--non-interactive', '--username', 'admin', '--password', 'Ddhi1lmi', '--no-auth-cache',
        #        'checkout', 'svn://192.168.1.50/xafc-test/test',
        #        '/tmp/bees/codes/3157a43701dab1a8eb16ee3b1a4d1498/revision']
        # # cmd = ['git', 'clone', '--branch=master', '-v', self.url, self.path]
        # import subprocess
        # env = os.environ.copy()
        # cwd = os.getcwd()
        # with subprocess.Popen(
        #     cmd,
        #     stdout=subprocess.PIPE,
        #     stderr=subprocess.STDOUT,
        #     cwd=cwd,
        #     env=env,
        #     # shell=True
        # ) as process:
        #     process.wait()
        :return:
        """
        return PyRepo.clone_from(url=self.url, to_path=self.path, branch='master')

    def pull(self):
        """
        更新项目

        @param branch:
        @param kwargs:
        @return:
        """
        repo = PyRepo(self.path)
        return repo.remote().pull(refspec='master')

    def checkout_2_branch(self, branch):
        """
        切换到某个分支

        @param branch:
        @return:
        """
        PyRepo(self.path).git.checkout(branch)

    def checkout_2_commit(self, branch, commit):
        """
        切换分支的某个commit

        @param branch:
        @param commit:
        @return:
        """
        self.checkout_2_branch(branch=branch)
        PyRepo(self.path).git.reset('--hard', commit)

    def checkout_2_tag(self, tag):
        """
        切换到tag

        @param tag:
        @return:
        """
        PyRepo(self.path).git.checkout(tag)

    def branches(self):
        """
        获取所有分支
        @return:
        """
        # 去除 origin/HEAD -> 当前指向
        # 去除远端前缀
        branches = PyRepo(self.path).remote().refs
        # fixbug https://github.com/meolu/walle-web/issues/705
        return [str(branch).strip().lstrip('origin').lstrip('/') for branch in branches if
                not str(branch).strip().startswith('origin/HEAD')]

    def tags(self):
        """
        获取所有tag，按时间倒序
        @return:
        """
        try:
            flag = 'v'
            tags = [tag.name.replace(flag, '') for tag in PyRepo(self.path).tags]
            tags = sorted(tags, key=cmp_to_key(compare_version))
            tags = ['{0}{1}'.format(flag, tag) for tag in tags]
        except Exception:
            tags = [tag.name for tag in PyRepo(self.path).tags]
        return tags

    def commits(self, branch):
        """
        获取分支的commits

        @param branch:
        @return:
        """
        self.checkout_2_branch(branch)

        commit_log = PyGit.Git(self.path).log('--pretty=%h #@_@# %an #@_@# %s', max_count=20)
        commit_list = commit_log.split('\n')
        commits = []
        for commit in commit_list:
            if not re.search('^.+ #@_@# .+ #@_@# .*$', commit):
                continue

            commit_dict = commit.split(' #@_@# ')
            commits.append({
                'id': commit_dict[0],
                'name': commit_dict[1],
                'message': commit_dict[2],
            })

        return commits

if __name__ == '__main__':
    git = Git(url='http://administrator:31HB6Dk7VmFIX8qd@coding.xafc.com/administrator/actBackend.git')
    # git.init(path='/tmp/bees/test/git', is_need_clone=True)
    #
    # print('branches-->', git.branches())
    # print('tags-->', git.tags())
    # print('commits-->', git.commits('master'))

    print('-----------')
    git.init(path='/tmp/bees/test/git', is_need_clone=True)
    git.checkout_2_tag('v1.1.10')
